package com.ruoyi.mobile.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.ruoyi.common.core.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;

import java.net.UnknownHostException;
import java.util.Date;
import java.util.Map;

@Slf4j
public class JwtUtils {
    // 生产环境不能这么用，生产环境应该生成公私密钥
    private static final String KEY = "********";
    private static final String ISSUER = "********";

    public static final long TOKEN_EXP_TIME = 10 * 24 * 60 * 60 * 1000;
    private static final String USER_NAME = "username";

    /**
     * 生成Token
     *
     * @param acctName
     * @return
     */
    public static String token(String acctName,String userId) {
        Date now = DateUtils.getNowDate();
        Algorithm algorithm = Algorithm.HMAC256(KEY);
        try {

            String token = JWT.create()
                    .withIssuer(ISSUER)
                    .withIssuedAt(now)
                    .withExpiresAt(new Date(now.getTime() + TOKEN_EXP_TIME))
                    .withClaim(USER_NAME, acctName + IPAddr.getLocalHostLANAddress().getHostAddress())
                    .withClaim("userId",userId)
                    .sign(algorithm);
            log.info("jwt generated user={}", acctName);
            return token;
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 校验Token
     *
     * @param token
     * @param username
     * @return
     */
    public static boolean verify(String token, String username,String userId) {
        log.info("verifying jwt - username={}", username);
        try {
            Algorithm algorithm = Algorithm.HMAC256(KEY);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .withClaim(USER_NAME, username + IPAddr.getLocalHostLANAddress().getHostAddress())
                    .withClaim("userId",userId)
                    .build();

            verifier.verify(token);
            return true;
        } catch (Exception e) {
            log.error("auth failed", e);
            return false;
        }
    }

    public static String getUserId(String token) {
        try {
            Map<String, Claim> claimsMap = JWT.decode(token).getClaims();
            if(!claimsMap.containsKey("userId")){
                return "";
            }
            return claimsMap.get("userId").asString();
        } catch (Exception e) {
            log.error("auth failed", e);
            return "";
        }
    }
}
